<?php
namespace app\common\model;

use think\facade\Db;
use hema\wechat\Driver;

/**
 * 公众号模型
 */
class Material extends BaseModel
{
    // 定义表名
    protected $name = 'material';

    // 定义主键
    protected $pk = 'material_id';

    // 追加字段
    protected $append = ['file_url'];
    
    /**
     * 关联图文素材集
     */
    public function text()
    {
        return $this->hasMany('app\\common\\model\\MaterialText','text_no','text_no');
    }
    
    /**
     * 文件类型
     */
    public function getFileTypeAttr($value)
    {
        $status = [10 => '图片', 20 => '音频', 30 => '视频', 40 => '图文'];
        return ['text' => $status[$value], 'value' => $value];
    }
    
    /**
     * 获取图片完整路径
    */ 
    public function getFileUrlAttr($value,$data)
    {
        return uploads_url() . '/' . $data['file_path'];
    }

    /**
     * 获取列表记录
     */
    public function getList($file_type = 0)
    {
        $applet_id = self::$applet_id;
        // 筛选条件
        $filter = [];
        empty($applet_id) && $filter['applet_id'] = 0;
        $file_type > 0 && $filter['file_type'] = $file_type;
        return $this->where($filter)->order(['material_id' => 'desc'])->paginate(['list_rows'=>15,'query' => request()->param()]);
    }

    /**
     * 根据图片名称获取详情
    */
    public static function getImage(string $file_path)
    {
        $applet_id = self::$applet_id;
        // 筛选条件
        $filter = [];
        empty($applet_id) && $filter['applet_id'] = 0;
        $filter['file_type'] = 10;
        $filter['file_path'] = $file_path;
        return self::where($filter)->find();
    }

    /**
     * 根据media_id获取详情
    */
    public static function mediaId($media_id)
    {
        $applet_id = self::$applet_id;
        // 筛选条件
        $filter = [];
        empty($applet_id) && $filter['applet_id'] = 0;
        $filter['media_id'] = $media_id;
        return self::where($filter)->with(['text'])->find();
    }

    /**
     * 添加新记录
     */
    public function add(array $data, string $file_path = '')
    {
        $wx = new Driver;
        $applet_id = self::$applet_id;
        empty($applet_id) && $applet_id = 0;
        $data['applet_id'] = $applet_id;
        if($data['file_type']!=10){
            $data['file_path'] = $file_path;
        }else{
            if(!isset($data['file_path'])){
                $this->error = '请选择要上传的素材';
                return false;
            }
        }
        //视频素材
        if($data['file_type']==30){
            $result = $wx->addMaterial($applet_id,$data['file_path'],$data['file_type'],$data['name'],$data['introduction']);
        }elseif($data['file_type']==10){
            //图片素材
            //验证封面图片是否已经上传到微信端
            if($result = self::getImage($data['file_path'])){
                $this->error = '该图片素材上传过了，记录编号：'.$result['material_id'];
                return false;
            }else{
                $result = $wx->addMaterial($applet_id,$data['file_path']);//没上传-执行上传
            }
            
        }else{
            //音频素材
            $result = $wx->addMaterial($applet_id,$data['file_path'],$data['file_type']);
        }
        if(!isset($result['media_id'])){
            $this->error = 'code：' . $result['errcode'] . '，msg：' . $result['errmsg'];
            return false;
        }
        $data['media_id'] = $result['media_id'];
        if($data['file_type']==10){//只有图片素材才返回url
            $data['url'] = $result['url'];
        }
        return $this->save($data);
    }
    
    /**
     * 更新
     */
    public function edit(array $data)
    {
        return $this->save($data) !== false;
    }

    /**
     * 删除
     */
    public function remove()
    {
        $wx = new Driver;
        $applet_id = self::$applet_id;
        empty($applet_id) && $applet_id = 0;
        if($this->file_type['value']==40){
            //删除图文集
            MaterialText::withoutGlobalScope()->where('text_no',$this->text_no)->delete();
            //删除素材
            $result = $wx->delDraft($this->media_id,$applet_id);
        }else{
            //删除素材
            $result = $wx->delMaterial($this->media_id,$applet_id);
        }
        if($result['errcode']!=0){
            $this->error = 'code：' . $result['errcode'] . '，msg：' . $result['errmsg'];
            return false;
        }
        if($this->file_type['value'] == 20 OR $this->file_type['value'] == 30){
            //删除视频、音频文件
            if(file_exists('./uploads/'.$this->file_path))
            {
                unlink('./uploads/'.$this->file_path);
            }
        }
        return $this->delete();
    }

    /**
     * 添加图文素材集
     */
    public function addText($data)
    {
        $wx = new Driver;
        $applet_id = self::$applet_id;
        empty($applet_id) && $applet_id = 0;
        //创建素材列表
        $material = array();
        //上传封面图
        for($n=0;$n<sizeof($data);$n++){
            //验证封面图片是否已经上传到微信端
            if($res = self::getImage($data[$n]['file_path'])){
                //上传过，获取信息
                $data[$n]['url']= $res['url'];
                $data[$n]['media_id']= $res['media_id'];
            }else{
                //没上传-执行上传
                $result = $wx->addMaterial($applet_id,$data[$n]['file_path']);
                if(!isset($result['media_id'])){
                    $this->error = 'code：' . $result['errcode'] . '，msg：' . $result['errmsg'];
                    return false;
                }
                $data[$n]['media_id'] = $result['media_id'];
                $data[$n]['url'] = $result['url'];
                array_push($material,[
                    'name' => '图文封面',
                    'file_path' => $data[$n]['file_path'],
                    'media_id' => $result['media_id'],
                    'url' => $result['url'],
                    'applet_id' => $applet_id
                ]);
            }           
        }
        //过滤正文部分的图片数据
        for($n=0;$n<sizeof($data);$n++){
            $data[$n]['content'] = html_entity_decode($data[$n]['content']);
            $result= $this->filterStr($data[$n]['content']);
            //判断正文中是否存在图片
            if(sizeof($result)==2){
                $img = $result['img'];
                //上传到微信端
                if(!$img = $wx->upWechatUrl($img,$applet_id)){
                    $this->error = '图片仅支持jpg/png格式，大小必须在1MB以下';
                    return false;
                }
                //二次过滤正文，替换掉占位符
                //$data[$n]['content'] = html_entity_decode($this->filterStrTwo($result['str'],$img));
                $data[$n]['wx_content'] = $this->filterStrTwo($result['str'],$img);
            }else{
                //富文本转码
                //$data[$n]['content'] = html_entity_decode($result['str']);
                $data[$n]['wx_content'] = $result['str'];
            }
        }
        //拼接数据提交到微信端
        $result = $wx->addDraft($data,$applet_id);
        if(!isset($result['media_id'])){
            $this->error = 'code：' . $result['errcode'] . '，msg：' . $result['errmsg'];
            return false;
        }
        $text_no = order_no();//生成素材集编号
        
         // 开启事务
        Db::startTrans();
        try {
            //添加到图文集表
            $model = new MaterialText;
            if(!$model->add($data,$text_no)){
                $this->error = '添加到图文集表错误';
            }
            //组成数据添加到素材表
            array_push($material,[
                'name' => $data[0]['name'],
                'file_type' => 40,
                'file_path' => $data[0]['file_path'],
                'media_id' => $result['media_id'],
                'text_no' => $text_no,
                'url' => $data[0]['url'],
                'applet_id' => $applet_id
            ]);
            if(!$this->saveAll($material)){
                $this->error = '添加到素材表错误';
            }
            Db::commit();
            return true;
        } catch (\Exception $e) {
            Db::rollback();
        }
        return false;
    }
    
    /**
     * 修改图文素材集
     */
    public function editText($data,$model)
    {
        $wx = new Driver;
        $applet_id = self::$applet_id;
        empty($applet_id) && $applet_id = 0;
        //创建素材列表
        $material = array();
        //上传封面图
        for($n=0;$n<sizeof($data);$n++){
            //验证封面图片是否已经上传到微信端
            if($res = self::getImage($data[$n]['file_path'])){
                //上传过，获取信息
                $data[$n]['url']= $res['url'];
                $data[$n]['media_id']= $res['media_id'];
            }else{
                //没上传-执行上传
                $result = $wx->addMaterial($applet_id,$data[$n]['file_path']);
                if(!isset($result['media_id'])){
                    $this->error = 'code：' . $result['errcode'] . '，msg：' . $result['errmsg'];
                    return false;
                }
                $data[$n]['media_id'] = $result['media_id'];
                $data[$n]['url'] = $result['url'];
                array_push($material,[
                    'name' => '图文封面',
                    'file_path' => $data[$n]['file_path'],
                    'media_id' => $result['media_id'],
                    'url' => $result['url']
                ]);
            }           
        }
        //过滤正文部分的图片数据
        for($n=0;$n<sizeof($data);$n++){
            $result= $this->filterStr($data[$n]['content']);
            //判断正文中是否存在图片
            if(sizeof($result)==2){
                $img = $result['img'];
                //上传到微信端
                if(!$img = $wx->upWechatUrl($img,$applet_id)){
                    $this->error = '图片仅支持jpg/png格式，大小必须在1MB以下';
                    return false;
                }
                //二次过滤正文，替换掉占位符
                //$data[$n]['content'] = html_entity_decode($this->filterStrTwo($result['str'],$img));
                $data[$n]['wx_content'] = html_entity_decode($this->filterStrTwo($result['str'],$img));
            }else{
                //富文本转码
                //$data[$n]['content'] = html_entity_decode($result['str']);
                $data[$n]['wx_content'] = html_entity_decode($result['str']);
            }
        }

        //拼接数据提交到微信端
        if(!$result = $wx->editDraft($data,$this->media_id,$applet_id)){
            $this->error = $wx->getError();
            return false;
        }
        
        // 开启事务
        Db::startTrans();
        try {
            //修改到图文集表
            if(!$model->edit($data)){
                $this->error = '图文素材列表修改错误';
            }
            //组成数据添加到素材表
            array_push($material,[
                'material_id' => $this->material_id,
                'name' => $data[0]['name'],
                'file_path' => $data[0]['file_path'],
                'url' => $data[0]['url']
            ]);
            if(!$this->saveAll($material)){
                $this->error = '图文素材修改错误';
            }
            Db::commit();
            return true;
        } catch (\Exception $e) {
            Db::rollback();
        }
        return false;
    }  
    
    /**
     * 过滤字符串中的链接/换成占位符
     */
    private function filterStr($str)
    {
        for($n=0;$n<99;$n++){ 
            //字符串 在$str 第一次出现的位置 索引0开始 没有出现返回false 不区分大小写
            $start = stripos($str,uploads_url().'/');
            if(!$start){
                $data['str'] = $str;
                return $data;
            }
            //获取截取长度
            $len = strlen(uploads_url().'/')+45;
            //截取字符串 $str 的第一个字符 截取长度3 长度不填默认截取到最后  参数为负数则倒数
            $data['img'][$n]['url'] = substr($str,$start,$len);
            //截取字符串,第N个字符 截取到最后
            $data['img'][$n]['file_path'] = substr($data['img'][$n]['url'],strlen(uploads_url().'/'));
            //替换占位符
            $str = str_ireplace($data['img'][$n]['url'],'he_ma'.$n,$str);
        }
    }
    
    /**
     * 二次过滤字符串中的占位符/换成安全的链接
     */
    private function filterStrTwo($str,$img)
    {
        for($n=0;$n<sizeof($img);$n++){ 
            //替换占位符
            $str = str_ireplace('he_ma'.$n,$img[$n]['url'],$str);
        }
        return $str;
    }

    /**
     * 新增图文素材默认数据
     */
    public function getDefault()
    {
        $data = [
            0 => [
                'name' => '',//素材集名称
                'title' => '',
                'author' => '',
                'content' => '',
                'url' => '/assets/img/diy/banner_01.jpg',
                'file_path' => '',
                'digest' => ''
            ]
        ];
        return json_encode($data);
    }

}
